package com.example.utils.json;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.utils.Config;
import com.example.utils.FileUtils;
import com.example.utils.StringUtils;
import com.example.utils.image.HttpUtils;
import org.apache.ibatis.io.Resources;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LEI
 * Created by LEI on 2020/3/13.
 */
public class EquipmentUtil {

    static List<Equipment> equipmentList;
    static Map<Integer,Equipment> equipmentMap;

    /**
     * 读取json文件，返回json串
     * @return
     */
    public static String readJsonFile() {
        String jsonStr = "";
        try {
            File jsonFile = new File(Config.EQUIPMENTS_JSON_PATH);
            if(!jsonFile.exists()){
                loadEquipmentsJson();
            }
            InputStream inputStream = null;
            try {
                inputStream = new FileInputStream(jsonFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            assert inputStream != null;
            Reader reader = new InputStreamReader(inputStream,"utf-8");
            int ch = 0;
            StringBuilder sb = new StringBuilder();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            inputStream.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**从网络加载武器JSON文件
     *
     * @return
     */
    public static boolean loadEquipmentsJson(){
        InputStream inputStreamByGet = HttpUtils.getInputStreamByGet(Config.JSON_URL);
        if(inputStreamByGet == null)return false;
        File file = new File(Config.EQUIPMENTS_JSON_PATH);
        try {
            FileUtils.writeToLocal(file,inputStreamByGet);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    public static void initEquipment(){
        String json = readJsonFile();
        JSONArray jsonArray = JSONArray.parseArray(json);
        if(jsonArray != null){
            equipmentList = new ArrayList<Equipment>(jsonArray.size());
            equipmentMap = new HashMap<Integer, Equipment>(jsonArray.size());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Equipment equipment = new Equipment();
                equipment.setId(jsonObject.getInteger("id"));
                equipment.setBaseType(jsonObject.getString("baseType"));
                equipment.setDesc(jsonObject.getString("desc"));
                equipment.setImg(jsonObject.getInteger("img"));
                equipment.setUid(jsonObject.getInteger("uid"));
                equipment.setTitle(jsonObject.getString("title"));
                equipment.setSeriesText(jsonObject.getString("seriesText"));
                equipment.setRarity(jsonObject.getInteger("rarity"));
                equipment.setMaxlv(jsonObject.getInteger("maxlv"));
                equipment.setCost(jsonObject.getInteger("cost") == null ? 0: jsonObject.getInteger("cost"));
                equipment.setDamageType(jsonObject.getString("damageType"));
                equipment.setSeriesId(jsonObject.getInteger("seriesId") == null ? 0: jsonObject.getInteger("seriesId"));
                equipment.setHpBase(jsonObject.getInteger("hpBase") == null ? 0: jsonObject.getInteger("hpBase"));
                equipment.setHpMaxLv(jsonObject.getInteger("hpMaxLv") == null ? 0: jsonObject.getInteger("hpMaxLv"));

                String damageMaxLv = jsonObject.getString("damageMaxLv");
                if(StringUtils.isNumString(damageMaxLv)){
                       equipment.setDamageMaxLv((int)Double.parseDouble(damageMaxLv));
                }
                String fireRateMaxLv = jsonObject.getString("fireRateMaxLv");
                if(StringUtils.isNumString(fireRateMaxLv)){
                    equipment.setFireRateMaxLv(Double.parseDouble(fireRateMaxLv));
                }
                String ammoMaxLv = jsonObject.getString("ammoMaxLv");
                if(StringUtils.isNumString(ammoMaxLv)){
                    equipment.setAmmoMaxLv((int)Double.parseDouble(ammoMaxLv));
                }

                String evolveFormula = jsonObject.getString("evolveFormula");
                if(StringUtils.isNotEmpty(evolveFormula)){
                    JSONObject json1 = jsonObject.getJSONObject("evolveFormula");
                    EvolveFormula evolveFormula1 = JSON.toJavaObject(json1,EvolveFormula.class);
                    equipment.setEvolveFormula(evolveFormula1);
                }


                // 武器
                equipment.setType(1);

                // 衣服
                if(equipment.getHpBase()>0&&StringUtils.isEmpty(equipment.getBaseType())){
                    equipment.setType(2);
                    equipment.setBaseType("服装");
                }

                // 使魔
                if(equipment.getCost() <= 0&&equipment.getHpBase()<=0){
                   equipment.setType(4);
                   equipment.setBaseType("使魔");
                }

                // 徽章
                if(equipment.getCost() >0 && StringUtils.isEmpty(equipment.getBaseType()) && equipment.getHpBase() <= 0){
                    equipment.setType(3);
                    equipment.setBaseType("徽章");
                }

                List<Skill> skills = new ArrayList<Skill>();
                List<DemonSkill> demonSkills = new ArrayList<DemonSkill>();
                if(equipment.getType() == 1 || equipment.getType() ==2 || equipment.getType() == 3){
                    if(jsonObject.get("prop1") != null){
                        Skill skill = setSkill(jsonObject, "prop1");
                        skills.add(skill);
                    }
                    if(jsonObject.get("prop2") != null){
                        Skill skill = setSkill(jsonObject, "prop2");
                        skills.add(skill);
                    }
                // 使魔
                }else if(equipment.getType() == 4){
                    if(jsonObject.get("ulrtaSkill") != null){
                        DemonSkill demonSkill = setDemonSkill(jsonObject,"ulrtaSkill");
                        demonSkills.add(demonSkill);
                    }
                    if(jsonObject.get("hiddenUltraSkill") != null){
                        DemonSkill demonSkill = setDemonSkill(jsonObject,"hiddenUltraSkill");
                        demonSkills.add(demonSkill);
                    }
                    if(jsonObject.get("normalSkill1") != null){
                        DemonSkill demonSkill = setDemonSkill(jsonObject,"normalSkill1");
                        demonSkills.add(demonSkill);
                    }
                    if(jsonObject.get("normalSkill2") != null){
                        DemonSkill demonSkill = setDemonSkill(jsonObject,"normalSkill2");
                        demonSkills.add(demonSkill);
                    }
                }

                equipment.setSkills(skills);
                equipment.setDemonSkills(demonSkills);
                equipmentList.add(equipment);
                equipmentMap.put(equipment.getUid(),equipment);
            }
        }
    }

    public static List<Equipment> getEquipmentList(){
        if(equipmentList == null){
            initEquipment();
        }
        return EquipmentUtil.equipmentList;
    }

    public static Skill setSkill(JSONObject jsonObject,String prop){
        JSONObject prop1 = jsonObject.getJSONObject(prop);
        Skill skill = new Skill();
        skill.setTitle(prop1.getString("title"));
        skill.setDamageType(prop1.getString("damageType"));
        skill.setDesc(StringUtils.replaceSpecialChar(prop1.getString("desc")));
        skill.setMaxLvDesc(StringUtils.replaceSpecialChar(prop1.getString("maxLvDesc")));
        return skill;
    }

    public static DemonSkill setDemonSkill(JSONObject jsonObject,String skill){
        JSONObject kill = jsonObject.getJSONObject(skill);
        DemonSkill demonSkill = new DemonSkill();
        demonSkill.setTitle(kill.getString("title"));
        demonSkill.setType(kill.getString("type"));
        demonSkill.setDesc(StringUtils.replaceSpecialChar(kill.getString("desc")));
        demonSkill.setMaxLvDesc(StringUtils.replaceSpecialChar(kill.getString("maxLvDesc")));
        return demonSkill;
    }

    public static Map<Integer,Equipment> getRelationEquipment(Equipment equipment,Map<Integer,Equipment> equipments){
       if(equipments == null){equipments = new HashMap<Integer, Equipment>();}
       if(equipment.getEvolveFormula() != null){
           List<EvolveFormulaItem> inputs = equipment.getEvolveFormula().getInput();
           if(inputs != null&&inputs.size()>0){
               for (EvolveFormulaItem input : inputs) {
                   // 获取通过我进化的装备IMG
                   int uid = input.getOutput();
                   // 判断是否已经放过该装备
                   if(equipments.containsKey(uid)){
                      continue;
                   }
                   Equipment equipment1 = equipmentMap.get(uid);
                   if(equipment1 != null){
                       equipments.put(equipment1.getUid(),equipment1);
                       getRelationEquipment(equipment1,equipments);
                   }
               }
           }
           List<EvolveFormulaItem> outputs = equipment.getEvolveFormula().getOutput();
           if(outputs != null&&outputs.size()>0){
               for (EvolveFormulaItem output : outputs) {
                   // 获取进化为我的装备
                   int uid = output.getInput();
                   // 判断是否已经放过该装备
                   if(equipments.containsKey(uid)){
                       continue;
                   }
                   Equipment equipment1 = equipmentMap.get(uid);
                   if(equipment1 != null){
                       equipments.put(equipment1.getUid(),equipment1);
                       getRelationEquipment(equipment1,equipments);
                   }
               }
           }
       }
       return equipments;
    }

    /**
     * 根据对象多个属性去重 属性：id + title
     * @param equipments
     * @return
     */
    public static List<Equipment> removeDistinctByIdAndTitle(List<Equipment> equipments){
        return equipments.stream().collect(Collectors
                .collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> {
                    // 根据useId和userName进行去重
                    return o.getId() + "," + o.getTitle();
                }))), ArrayList::new));
    }

    /**
     * 根据对象属性去重  属性：title
     * @param equipments
     * @return
     */
    public static List<Equipment> removeDistinctByTitle(List<Equipment> equipments) {
        Set<Equipment> personSet = new TreeSet<>((o1, o2) -> o1.getTitle().compareTo(o2.getTitle()));
        personSet.addAll(equipments);
        return new ArrayList<>(personSet);
    }
}
